package com.paw.core.aop;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import com.paw.core.annotation.SkipResponseLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 日志切面抽象类
 */
public abstract class AbstractWebLogAspect {
  private final Logger logger = LoggerFactory.getLogger(getClass());

  /** 切点 ：实现类需声明切点的包名 */
  protected abstract void webLog();

  /**
   * 前置处理，记录请求信息
   *
   * @param joinPoint
   *            joinPoint
   * @throws Throwable
   *             Throwable
   */
  @Before("webLog()")
  protected void doBefore(JoinPoint joinPoint) throws Throwable {
    try {
      MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

      ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
      HttpServletRequest request = attributes.getRequest();

      StringBuilder builder = new StringBuilder();
      builder.append("\n     class name : ").append(methodSignature.getDeclaringTypeName());
      builder.append("\n   class method : ").append(methodSignature.getName());
      builder.append("\n    request url : ").append(request.getRequestURL());
      builder.append("\n request method : ").append(request.getMethod());
      builder.append("\n     class args : ").append(JSON.toJSONString(joinPoint.getArgs()));
      builder.append("\n");
      logger.info(builder.toString());

    } catch (Exception e) {
      logger.error("aop error : " + e.getMessage());
    }
  }

  /**
   * 后置处理，记录结果信息
   */
  @AfterReturning(returning = "result", pointcut = "webLog()")
  protected void doAfterReturning(JoinPoint joinPoint,Object result) throws Throwable {
    try {
      if (null==result) {
        logger.info("aop json response : result is null !");
        return;
      }
      if (result.toString().startsWith("<xml>")) {
        logger.info("aop xml response : \n" + result);
      } else {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        SkipResponseLog skipResponseLog = methodSignature.getMethod().getAnnotation(SkipResponseLog.class);
        if (null == skipResponseLog) {
          logger.info("aop json response : \n" + JSON.toJSONString(result));
        }
      }
    } catch (Exception e) {
      logger.error("aop error response : " + result);
    }
  }
}
